/*
 * TestBigInteger.cpp
 *
 *  Created on: 2010-3-11
 *      Author: liheyuan
 *    Describe: 
 *
 *   Last Date: 2010-3-11
 *   CopyRight: 2010 @ ICT LiHeyuan
 */

#include <iostream>
#include <sstream>
using std::cout;
using std::endl;
using std::ostringstream;

#include "../include/BigInteger.h"

//测试转换成字符串和从字符串转换而来
void testStringIO()
{
	BigInteger bint("137529840731792307993117");
	cout << bint.toString() << endl;
	/*	BigInteger bint("1");
	 cout << bint.toString() << endl;*/
}

//测试加法
void testAdd()
{
	/*	BigInteger bint1("137529840731792307993117");
	 BigInteger bint2("999999999999999999999999");
	 cout << (bint1 + bint2).toString() << endl;*/

	BigInteger bint3("0");
	BigInteger bint4("-0");
	cout << (bint3 + bint4).toString() << endl;

}

//用加法模拟乘法，实现1～100的接乘
/*
 void testJieChengFake() {
 BigInteger arr[101];
 arr[1] = BigInteger("1");
 for (int i = 2; i <= 100; i++) {
 arr[i] = arr[i - 1] * i;
 }
 cout << arr[100].toString() << endl;
 }
 */

//使用正版operator +实现接乘法
void testJieCheng()
{
	BigInteger arr[1001];
	arr[1] = BigInteger(1);
	for (int i = 2; i <= 1000; i++)
	{
		BigInteger x = BigInteger(i);
		arr[i] = arr[i - 1] * x;
	}
	cout << arr[1000].toString() << endl;
	cout << arr[1000].size() << endl;
}

void testGetAt()
{
	BigInteger bint("137529840731792307993117");
	for (int i = bint.size() - 1; i >= 0; i--)
	{
		cout << bint.getAt(i);
	}
	cout << endl;
}

void testMultiply()
{
	BigInteger
			bint1(
					"103969085482428483289557172002238384635097099689535273500973739191278209612683467514583446680354725306135516075310364074220170819348535138345335429155291720349641708817378700221899880942330363189300693072015698490273311501930080854926906552091892511830048193130979122934026464568336567673175563105743559803431");
	BigInteger
			bint2(
					"119069974407473647120249211300456662941687067908900590925433205132837447080930999428101180945592842306266207208202279574868218371466433885059462536277970664412933196616822201741843332949320269765662861945950159129886341464692363759656084538549665491922151628530409762531429542162771713410584176187378444966547");
	cout << (bint1 * bint2).toString() << endl;
}

//测试减法
void testSubstract()
{
	BigInteger a("-0");
	BigInteger b("-0");
	cout << (a - b).toString() << endl;
}

//测试绝对值距离
void testAbsDiff()
{
	BigInteger a("136666");
	BigInteger b("0");
	cout << a.absDiff(b) << endl;
}

//测试<符号
void testSmallerThan()
{
	BigInteger a("10");
	BigInteger b("0");
	cout << (a < b) << endl;
}

//测试相等
void testEqual()
{
	BigInteger a;
	BigInteger b;
	cout << (a == b) << endl;
}

//测试>符号
void testBiggerThan()
{
	BigInteger a("12453571");
	BigInteger b("0");
	cout << (a > b) << endl;
}

void testDivAndMod()
{
	BigInteger
			a(
					"103969085482428483289557172002238384635097099689535273500973739191278209612683467514583446680354725306135516075310364074220170819348535138345335429155291720349641708817378700221899880942330363189300693072015698490273311501930080854926906552091892511830048193130979122934026464568336567673175563105743559803431");
	BigInteger b("17");
	BigInteger shang, yu;
	//cout << a.toString() << endl;
	a.divAndMod(b, shang, yu);
	cout << shang.toString() << " " << yu.toString() << endl;
}

void testMod()
{
	BigInteger a("1");
	BigInteger b("1");
	/*	cout << a.toString() << " % " << b.toString() << " = "
	 << (a % b) << endl;*/
}

void testGcd()
{
	BigInteger
			a(
					"103969085482428483289557172002238384635097099689535273500973739191278209612683467514583446680354725306135516075310364074220170819348535138345335429155291720349641708817378700221899880942330363189300693072015698490273311501930080854926906552091892511830048193130979122934026464568336567673175563105743559803431");
	/*	cout << a.gcd(b).toString() << endl;*/
}

void fastMod()
{
	BigInteger
			a(
					"103969085482428483289557172002238384635097099689535273500973739191278209612683467514583446680354725306135516075310364074220170819348535138345335429155291720349641708817378700221899880942330363189300693072015698490273311501930080854926906552091892511830048193130979122934026464568336567673175563105743559803431");
	for (UNIT_TYPE i = 1; i < 100; i++)
	{
		cout << i << " : " << (a % i) << endl;
	}
}

void testIsProbalePrime()
{

	BigInteger a = BigInteger::getRandomBigInteger(1024);
	if (a % 2 == 0)
	{
		a = a + 1;
	}
	int i = 0;
	while (true)
	{
		if (a.isProbalePrime())
		{
			break;
		}
		else
		{
			a = a + 2;
			i++;
		}
	}
	cout << a.toString() << endl;
	cout << i << endl;
}

void testSlowMod()
{
	BigInteger a("354");
	BigInteger b("2000000000000000");
	cout << a.slowMod(b).toString() << endl;
}

void testModBigInteger()
{
	BigInteger a(
			"1234565425345464564564563463476855465634757643747436436436789");
	BigInteger b("44444444444444444444444444444444444435345434");
	cout << (a % b).toString() << endl;
}

void testMod2()
{
	BigInteger a(
			"12345654253454645645645634634768554656347576437474364364367893");
	cout << a.div2().toString() << endl;
}

void testModPow()
{
	BigInteger a("5");
	BigInteger e("198744455656476545645");
	BigInteger m("17");

	cout << a.modPow(e, m).toString() << endl;
}

void testmillerRabin()
{
	BigInteger a("103969085482428483289557172002238384635097099689535273500973739191278209612683467514583446680354725306135516075310364074220170819348535138345335429155291720349641708817378700221899880942330363189300693072015698490273311501930080854926906552091892511830048193130979122934026464568336567673175563105743559803431");
	cout << a.isProbalePrime();
}

int main()
{
	//testStringIO();
	//testAdd();
	//testJieCheng();
	//testGetAt();
	//testMultiply();
	//testJieCheng();
	//testSubstract();
	//testAbsDiff();
	//testSmallerThan();
	//testEqual();
	//testBiggerThan();
	//testDivAndMod();
	//testMod();
	//testGcd();
	//fastMod();
	//testIsProbalePrime();
	//testSlowMod();
	//testModBigInteger();
	//testMod2();
	//testModPow();
	testmillerRabin();
}

